import { create } from 'zustand'
import { subscribeWithSelector } from 'zustand/middleware'
import { io, Socket } from 'socket.io-client'
import type { ServerToClientEvents, ClientToServerEvents } from '../types'

// 动态获取WebSocket URL
const getSocketURL = (): string => {
  const envUrl = import.meta.env.VITE_SOCKET_URL

  // 如果设置为auto，则根据当前页面URL动态生成
  if (envUrl === 'auto') {
    const currentHost = window.location.hostname
    const currentProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
    return `${currentProtocol}//${currentHost}:3001`
  }

  // 使用环境变量中的URL
  return envUrl || 'ws://localhost:3001'
}

const SOCKET_URL = getSocketURL()
const FALLBACK_URLS = import.meta.env.VITE_FALLBACK_SOCKET_URLS?.split(',') || [
  'wss://192.168.137.122:3001',
  'https://192.168.137.122:3001',
  'ws://192.168.137.122:3001',
  'http://192.168.137.122:3001',
  'wss://192.168.3.17:3001',
  'https://192.168.3.17:3001',
  'ws://192.168.3.17:3001',
  'http://192.168.3.17:3001',
  'wss://localhost:3001',
  'ws://localhost:3001',
];

type SocketClient = Socket<ServerToClientEvents, ClientToServerEvents>

interface SocketStoreState {
  // 状态
  socket: SocketClient | null;
  isConnected: boolean;
  isConnecting: boolean;
  connectionError: string | null;
  lastPing: number | null;
  reconnectAttempts: number;
  maxReconnectAttempts: number;
  currentUrlIndex: number;
  currentSocketUrl: string;

  // 方法
  connect: () => void;
  disconnect: () => void;
  emit: (event: string, data?: any) => boolean;
  on: (event: string, callback: (...args: any[]) => void) => () => void;
  off: (event: string, callback?: (...args: any[]) => void) => void;
  ping: () => void;
  getConnectionStatus: () => 'connected' | 'connecting' | 'error' | 'reconnecting' | 'disconnected';
  resetConnection: () => void;
  forceReconnect: () => void;
  tryNextUrl: () => void;
}

export const useSocketStore = create<SocketStoreState>()(
  subscribeWithSelector((set, get) => ({
    // 状态
    socket: null,
    isConnected: false,
    isConnecting: false,
    connectionError: null,
    lastPing: null,
    reconnectAttempts: 0,
    maxReconnectAttempts: 5,
    currentUrlIndex: 0,
    currentSocketUrl: SOCKET_URL,

    // 连接方法
    connect: () => {
      const { isConnected, isConnecting, currentSocketUrl } = get()

      if (isConnected || isConnecting) {
        return
      }

      set({ isConnecting: true, connectionError: null })
      console.log(`尝试连接到: ${currentSocketUrl}`)

      try {
        const newSocket: SocketClient = io(currentSocketUrl, {
          transports: ['websocket', 'polling'],
          timeout: 10000,
          reconnection: true,
          reconnectionAttempts: 5,
          reconnectionDelay: 1000,
          reconnectionDelayMax: 5000,
          // maxHttpBufferSize: 1e8, // 移除不支持的选项
          // pingTimeout: 60000, // 移除不支持的选项
          // pingInterval: 25000 // 移除不支持的选项
        })

        // 连接成功
        newSocket.on('connect', () => {
          console.log('Socket connected:', newSocket.id)
          set({ 
            socket: newSocket,
            isConnected: true, 
            isConnecting: false,
            connectionError: null,
            reconnectAttempts: 0
          })

          // 发送自定义事件通知其他组件进行设备注册
          window.dispatchEvent(new CustomEvent('socket-connected', { 
            detail: { socket: newSocket } 
          }))

          // 立即尝试注册设备
          setTimeout(async () => {
            try {
              const { useDeviceStore } = await import('../stores/deviceStore')
              const deviceStore = useDeviceStore.getState()
              
              if (!deviceStore.isRegistered) {
                console.log('🔄 Socket连接后自动注册设备...')
                await deviceStore.registerDevice(newSocket)
                console.log('✅ 设备自动注册成功')
              }
            } catch (error) {
              console.error('❌ 自动设备注册失败:', error)
            }
          }, 500) // 给设备存储一点时间初始化
        })

        // 通配符事件监听器，用于调试所有收到的事件
        newSocket.onAny((eventName, ...args) => {
          console.log(`[SocketStore DEBUG] 收到事件: '${eventName}'，数据:`, args);
        });

        // 连接失败
        newSocket.on('connect_error', (error) => {
          console.error(`Socket connection error to ${currentSocketUrl}:`, error)
          const state = get()

          // 如果还有其他URL可以尝试，则切换URL
          if (state.currentUrlIndex < FALLBACK_URLS.length - 1) {
            console.log('尝试下一个服务器地址...')
            get().tryNextUrl()
            return
          }

          set(state => ({
            isConnecting: false,
            connectionError: `连接失败: ${error.message}`,
            reconnectAttempts: state.reconnectAttempts + 1
          }))
        })

        // 断开连接
        newSocket.on('disconnect', (reason) => {
          console.log('Socket disconnected:', reason)
          set({ 
            isConnected: false,
            socket: null
          })
        })

        // 心跳检测 - 使用any类型处理Socket.io内置事件
        ;(newSocket as any).on('pong', () => {
          set({ lastPing: Date.now() })
        })

        // 重连事件
        ;(newSocket as any).on('reconnect', (attemptNumber: number) => {
          console.log('Socket reconnected after', attemptNumber, 'attempts')
          set({ reconnectAttempts: 0 })
        })

        ;(newSocket as any).on('reconnect_attempt', (attemptNumber: number) => {
          console.log('Socket reconnect attempt:', attemptNumber)
          set({ reconnectAttempts: attemptNumber })
        })

        ;(newSocket as any).on('reconnect_failed', () => {
          console.error('Socket reconnection failed')
          set({
            connectionError: '重连失败，请检查网络连接',
            isConnecting: false
          })
        })

        set({ socket: newSocket })

      } catch (error) {
        console.error('Failed to create socket:', error)
        const errorMessage = error instanceof Error ? error.message : 'Socket连接失败'
        set({
          isConnecting: false,
          connectionError: errorMessage
        })
      }
    },

    // 断开连接
    disconnect: () => {
      const { socket } = get()
      if (socket) {
        socket.disconnect()
        set({ 
          socket: null,
          isConnected: false,
          isConnecting: false,
          connectionError: null
        })
      }
    },

    // 发送消息
    emit: (event: string, data?: any) => {
      const { socket, isConnected } = get()
      console.log('📤 SocketStore: 尝试发送事件:', {
        event,
        hasSocket: !!socket,
        isConnected,
        socketId: socket?.id,
        data: data || '无数据'
      })
      
      if (socket && isConnected) {
        console.log('✅ SocketStore: 发送事件成功:', event, data ? '(有数据)' : '(无数据)')
        socket.emit(event as any, data)
        return true
      }
      console.warn('❌ SocketStore: Socket未连接，无法发送事件:', event)
      return false
    },

    // 监听事件
    on: (event: string, callback: (...args: any[]) => void) => {
      const { socket } = get()
      if (socket) {
        socket.on(event as any, callback)
        return () => socket.off(event as any, callback)
      }
      return () => {}
    },

    // 移除事件监听
    off: (event: string, callback?: (...args: any[]) => void) => {
      const { socket } = get()
      if (socket) {
        if (callback) {
          socket.off(event as any, callback)
        } else {
          socket.off(event as any)
        }
      }
    },

    // 发送心跳
    ping: () => {
      const { socket, isConnected } = get()
      if (socket && isConnected) {
        ;(socket as any).emit('ping')
      }
    },

    // 获取连接状态
    getConnectionStatus: () => {
      const { isConnected, isConnecting, connectionError, reconnectAttempts } = get()
      
      if (isConnected) return 'connected'
      if (isConnecting) return 'connecting'
      if (connectionError) return 'error'
      if (reconnectAttempts > 0) return 'reconnecting'
      return 'disconnected'
    },

    // 重置连接状态
    resetConnection: () => {
      set({
        connectionError: null,
        reconnectAttempts: 0
      })
    },

    // 强制重连
    forceReconnect: () => {
      const { disconnect, connect } = get()
      disconnect()
      setTimeout(() => {
        connect()
      }, 1000)
    },

    // 尝试下一个URL
    tryNextUrl: () => {
      const state = get()
      const nextIndex = (state.currentUrlIndex + 1) % FALLBACK_URLS.length
      const nextUrl = FALLBACK_URLS[nextIndex]

      console.log(`切换到服务器地址: ${nextUrl}`)

      // 断开当前连接
      if (state.socket) {
        state.socket.disconnect()
      }

      // 更新URL并重新连接
      set({
        socket: null,
        isConnected: false,
        currentUrlIndex: nextIndex,
        currentSocketUrl: nextUrl,
        connectionError: null
      })

      // 延迟重连
      setTimeout(() => {
        get().connect()
      }, 1000)
    }
  }))
)

// 自动心跳检测
setInterval(() => {
  const { ping, isConnected } = useSocketStore.getState()
  if (isConnected) {
    ping()
  }
}, 30000) // 每30秒发送一次心跳
